﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Transactions;
using System.Text;
using DAL;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.ComponentModel;


namespace BOL
{
    [Serializable]
    public class PresupuestoBL
    {

        #region "CRUD"

        public int add(string descripcion,
                string nombre,
                string abreviacion,
                DateTime fecha,
                int idObra,
                int idMoneda,
                decimal tipoCambio,
                List<PartidadEditInfo> partidaList,
                List<RecursoEditInfo> recursoList)
        {

            // GENRADOS POR EL SISTEMA

            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
            
           


            using (TransactionScope ts = new TransactionScope())
            {             
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);
                //--------------------
                bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    1,
                    idObra,
                    2);
                //----


                Presupuesto db = new Presupuesto();

                db.Add(_db,
                db.getCorrelativo(_db,idObra,1),
                descripcion,
                nombre,
                abreviacion,
                fecha,
                idEmpleadoEmisor,
                idObra,
                idMoneda,
                tipoCambio,
                1,
                23,
                ""); 
                
                SubPresupuesto dbsubPre = new SubPresupuesto();
                dbsubPre.codigo = db.codigo;
                dbsubPre.Descripcion = db.descripcion;
                dbsubPre.idPresupuesto = db.idInternal;
                db.SubPresupuesto.Add(dbsubPre);
                _db.SubmitChanges();

                foreach (PartidadEditInfo item in partidaList)
                {
                    if (item.idInternal == 0)
                    {
                        continue;
                    }
                    Partida partida= new Partida();

                    partida.Add(_db,
                        partida.getCorrelativo(_db, db.idInternal),
                        item.descripcion,
                        dbsubPre.idInternal,
                        db.idInternal);
                   
                   
                    foreach (var itemr in recursoList)
	                {
                        if (itemr.idInternal == 0)
                        {
                            continue;
                        }
                        if (itemr.idPartida == item.idInternal)
                        {
                            Recurso recurso = new Recurso();

                            recurso.Add(_db,
                                itemr.idInsumo,
                                itemr.codigo,
                                itemr.descripcion,
                                itemr.unidad,
                                itemr.cuadrilla,
                                itemr.cantidad,
                                itemr.precio,
                                itemr.parcial,
                                partida.idInternal,
                                27,
                                0,
                                null);

                            
                           
                        }
                    }
                    Rendimiento rendimiento = new Rendimiento();
                    rendimiento.Add(_db,
                        item.rendimiento,
                        item.valor,
                        item.EQ,
                        item.eqValor.Value,
                        item.costoAfecMetrado,
                        partida.idInternal,
                        rendimiento.GetMontoRecurso(_db, partida.idInternal));
                    
                    
                }
                db.updateTotal(_db);
               

                ts.Complete();

                return db.idInternal;
            }
        }


        public int add(string descripcion,
               string abreviacion,
               int idObra,
               int idMoneda)
        {

            
            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
            



            using (TransactionScope ts = new TransactionScope())
            {
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);
                //--------------------
                bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    1,
                    idObra,
                    2);
                //----


                Presupuesto db = new Presupuesto();
                decimal tipoCambio = _db.Obras.Single(p => p.idInternal == idObra).tipoCambio.Value;
                

                db.Add(_db,
                db.getCorrelativo(_db, idObra, 1),
                descripcion,
                descripcion,
                abreviacion,
                DateTime.Now,
                idEmpleadoEmisor,
                idObra,
                idMoneda,
                tipoCambio,
                1,
                23,
                "");

                SubPresupuesto dbsubPre = new SubPresupuesto();
                dbsubPre.codigo = db.codigo;
                dbsubPre.Descripcion = db.descripcion;
                dbsubPre.idPresupuesto = db.idInternal;
                db.SubPresupuesto.Add(dbsubPre);
                _db.SubmitChanges();

                ts.Complete();

                return db.idInternal;
            }
        }



        public bool update(int idPresupuesto,
           string nombre,
           string abreviacion
           )
        {
            bool result = false;
            int idEmpleado = int.Parse(HttpContext.Current.Session["idEmpleado"].ToString());

            using (TransactionScope ts = new TransactionScope())
            {
            

                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                Presupuesto dbObject = _db.Presupuesto.Single(p => p.idInternal == idPresupuesto);

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());



                //--------------------
                bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    1,
                    dbObject.idObra.Value,
                    3);
                //----



                SubPresupuesto dbsubpresupuesto = _db.SubPresupuesto.Single(p => p.idPresupuesto == idPresupuesto);
                //26 presupuesto  aprobado

                if (dbObject.idEstado == 26 | dbObject.idEstado == 25)
                {
                    throw new Exception("El presupuesto no pude ser actualizado  , verifique estado del  presupuesto");
                }

                
                dbObject.update(_db, nombre, abreviacion, idEmpleado);
                dbObject.updateTotal(_db);
                ts.Complete();
                result = true;
            }
            return result;
        }



        public bool update(int idPresupuesto,
            string nombre, 
            string abreviacion,
            DataSet entityList)
        {
            bool result = false;
                int idEmpleado= int.Parse(HttpContext.Current.Session["idEmpleado"].ToString());
            
           

            using (TransactionScope ts = new TransactionScope())
            {
                DataSet dsDiferencias = new DataSet();

                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

               Presupuesto dbObject = _db.Presupuesto.Single(p => p.idInternal == idPresupuesto);

               int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
            


               //--------------------
               bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                   idEmpleadoEmisor,
                   1,
                   dbObject.idObra.Value,
                   3);
               //----



               SubPresupuesto dbsubpresupuesto = _db.SubPresupuesto.Single(p => p.idPresupuesto == idPresupuesto);
                //26 presupuesto  aprobado

                 if (dbObject.idEstado == 26 | dbObject.idEstado == 25)
                {
                    throw new Exception("El presupuesto no pude ser actualizado  , verifique estado del  presupuesto");
                }

                

                if (entityList.HasChanges())
                {
                    dsDiferencias.Merge(entityList.GetChanges());
                    
                    foreach (DataRow drw in dsDiferencias.Tables["PartidadEditInfo"].Rows)
                    {
                        //siempre ingresa pues los valores son actualizados

                        if (drw.RowState == DataRowState.Modified)
                        {

                            Partida partidadb =
                                       _db.Partidas.Single(p => p.idInternal == drw.Field<Int32>("IdInternal"));
                           
                            partidadb.codigo = drw.Field<string>("codigo");
                            partidadb.descripcion = drw.Field<string>("descripcion");
                             _db.SubmitChanges();

                            foreach (DataRow drwr in dsDiferencias.Tables["RecursoEditInfo"].Rows)
                            {
                                if (drwr.RowState == DataRowState.Added)
                                {
                                    if (drwr.Field<int>("idPartida") == drw.Field<int>("idInternal"))
                                    {
                                        Recurso r = new Recurso();
                                        r.Add(_db,
                                            drwr.Field<int>("idInsumo"),
                                            drwr.Field<string>("codigo"),
                                            drwr.Field<string>("descripcion"),
                                            drwr.Field<string>("unidad"),
                                            drwr.Field<decimal>("cuadrilla"),
                                            drwr.Field<decimal>("cantidad"),
                                            drwr.Field<decimal>("precio"),
                                            drwr.Field<decimal>("parcial"),
                                            partidadb.idInternal,
                                            27,
                                            0,
                                            null);

                                        // r.parcialMonBase = Math.Round(drwr.Field<decimal>("parcial") * dbObject.tipoCambio.Value, 4);

                                    }
                                }
                                if (drwr.RowState == DataRowState.Modified)
                                {
                                    if (drwr.Field<int>("idPartida") == drw.Field<int>("idInternal"))
                                    {

                                        Recurso recursodb = _db.Recursos.Single(p => p.idInternal == drwr.Field<int>("idInternal"));

                                        if (!this.ExisteUsoRecurso(_db, drwr.Field<int>("idInternal")))
                                        {
                                             recursodb.Update(_db,
                                             drwr.Field<int>("idInsumo"),
                                             drwr.Field<string>("codigo"),
                                             drwr.Field<string>("descripcion"),
                                             drwr.Field<string>("unidad"),
                                             drwr.Field<decimal>("cuadrilla"),
                                             drwr.Field<decimal>("cantidad"),
                                             drwr.Field<decimal>("precio"),
                                             drwr.Field<decimal>("parcial"),
                                             0);
                                        }
                                    }
                                }
                                if (drwr.RowState == DataRowState.Deleted)
                                {
                                    drwr.RejectChanges();
                                    if (drwr.Field<int>("idPartida") == drw.Field<int>("idInternal"))
                                    {
                                        Recurso recursodb =
                                            _db.Recursos.Single(p => p.idInternal == drwr.Field<int>("idInternal"));

                                        if (!this.ExisteUsoRecurso(_db, drwr.Field<int>("idInternal")))
                                        {
                                            _db.Recursos.DeleteOnSubmit(recursodb);
                                        }

                                        
                                    }
                                }
                                _db.SubmitChanges();


                            }

                            Rendimiento rendimeintodb = _db.Rendimiento.Single(p => p.idInternal == drw.Field<Int32>("idRendimiento"));

                            rendimeintodb.Update(_db,
                                drw.Field<string>("rendimiento"),
                                drw.Field<String>("EQ"),
                                drw.Field<decimal>("valor"),
                                rendimeintodb.GetMontoRecurso(_db, rendimeintodb.idPartida.Value),
                                drw.Field<decimal>("costoAfecMetrado"),
                                drw.Field<decimal>("eqValor"));
                            


                        }



                        //-------------------------



                        if (drw.RowState == DataRowState.Deleted)
                        {
                            drw.RejectChanges();
                            

                            Partida  partidadb =_db.Partidas.Single(p => p.idInternal ==drw.Field<int>("IdInternal"));
                            Rendimiento rendiminetodb =_db.Rendimiento.Single(w => w.idPartida == drw.Field<int>("idInternal"));

                            verificarusoPartida(_db, partidadb.idInternal);
                            
                            // por cada  partida  eliminamos sus recursos
                                var recurso = from a in _db.Recursos
                                          where a.idPartida == partidadb.idInternal
                                          select a;

                            // los recursos no deben eliminarse si se encuetra utilizado
                                foreach (var r in recurso)
                                {
                                    if (r.parcialUso > 0)
                                    {
                                        throw new Exception("El recurso:"+r.codigo+"se encuentra utilizado");
                                    }

                                }


                            _db.Recursos.DeleteAllOnSubmit(recurso);
                            _db.Rendimiento.DeleteOnSubmit(rendiminetodb);
                            _db.Partidas.DeleteOnSubmit(partidadb);
                            _db.SubmitChanges();
                        }

                        if (drw.RowState == DataRowState.Added)
                        {
                            
                            Partida parti = new Partida();
                           
                                parti.Add(_db,
                                        parti.getCorrelativo(_db, dbObject.idInternal),
                                        drw.Field<string>("descripcion"),
                                        dbsubpresupuesto.idInternal,
                                        idPresupuesto);


                            foreach (DataRow drwr in dsDiferencias.Tables["RecursoEditInfo"].Rows)
                            {
                                if (drwr.RowState == DataRowState.Added &
                                    drwr.Field<int>("idPartida") == drw.Field<int>("idInternal"))
                                {
                                    Recurso r = new Recurso();
                                    r.Add(_db,
                                        drwr.Field<int>("idInsumo"),
                                        drwr.Field<string>("codigo"),
                                        drwr.Field<string>("descripcion"),
                                        drwr.Field<string>("unidad"),
                                        drwr.Field<decimal>("cuadrilla"),
                                        drwr.Field<decimal>("cantidad"),
                                        drwr.Field<decimal>("precio"),
                                        drwr.Field<decimal>("parcial"),
                                        parti.idInternal,
                                        27, 0,null);

                                    //r.parcialMonBase = Math.Round(drwr.Field<decimal>("parcial")* dbObject.tipoCambio.Value,4);
                                    
                                }
                               
                            }
                            Rendimiento rendimiento = new Rendimiento();
                            rendimiento.Add(_db,
                                drw.Field<string>("rendimiento"),
                                drw.Field<decimal>("valor"),
                                drw.Field<String>("EQ"),
                                drw.Field<decimal>("eqValor"),
                                drw.Field<decimal>("costoAfecMetrado"),
                                parti.idInternal,
                                rendimiento.GetMontoRecurso(_db, parti.idInternal));
                        }
               
                }
                }
                dbObject.update(_db, nombre, abreviacion, idEmpleado);
                dbObject.updateTotal(_db);
               ts.Complete();
                result = true;
            }
            return result;
        }

        

        private void CreateAdicion(dbGestionDataContext _db,Presupuesto presupuesto,int idUsuarioCre)
        {
            // registramos el presupuesto adicional

            string PrecuspuestoAdd = String.Format("ADIC {0}", presupuesto.abreviacion);

            Presupuesto PresupuestoAdicional = new Presupuesto();
            PresupuestoAdicional.AddAdicional(_db,
                                               presupuesto.codigo,
                                               PrecuspuestoAdd,
                                               PrecuspuestoAdd,
                                               PrecuspuestoAdd,
                                               presupuesto.fecha.Value,
                                               idUsuarioCre,
                                               presupuesto.idObra.Value,
                                               presupuesto.idMoneda.Value,

                                               presupuesto.idInternal);

            //luego esto debe estan en la dao
            SubPresupuesto dbsubPre2 = new SubPresupuesto();
            dbsubPre2.codigo = PresupuestoAdicional.codigo;
            dbsubPre2.Descripcion = PresupuestoAdicional.descripcion;
            dbsubPre2.idPresupuesto = PresupuestoAdicional.idInternal;
            _db.SubPresupuesto.InsertOnSubmit(dbsubPre2);
            _db.SubmitChanges();

        }

        public bool updateAprobacion(int idPresupuesto)
        {
            //el presupuesto es el  debe de estar  generado
            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {
                    int idEmpleado = int.Parse(HttpContext.Current.Session["idEmpleado"].ToString());

                    Presupuesto presupuesto = _db.Presupuesto.Single(p => p.idInternal == idPresupuesto);
                    var empleadoobra = from a in _db.EmpleadoObras
                                       where a.idEmpleado == idEmpleado &
                                       a.idObra == presupuesto.idObra
                                       select a;

                    if (empleadoobra.Count() == 0)
                    {
                        throw new Exception("No tiene acceso a la obra ingresada");
                    }
                    Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == empleadoobra.First().idRol);

                    if (rolEmpleado.nivelPrespuesto == 0)
                    {
                        throw new Exception("No tiene acceso Aprobar Presupuesto");
                    }
                    if (rolEmpleado.nivelPrespuesto == 1)
                    {
                        if (presupuesto.idEstado == 26)
                        {
                            throw new Exception("El presupuesto ya se encuentra Aprobado");
                        }
                        presupuesto.updateRevisor(_db, idEmpleado);
                    }

                    if (rolEmpleado.nivelPrespuesto == 2)
                    {

                        if (presupuesto.idEstado == 26)
                        {
                            throw new Exception("El presupuesto ya se encuentra Aprobado");
                        }
                        if (presupuesto.idEmpleadoRevisor == null)
                        {
                            presupuesto.updateRevisor(_db, idEmpleado);
                        }
                        presupuesto.updateAutorizado(_db, idEmpleado);
                        this.CreateAdicion(_db, presupuesto, idEmpleado);

                        //debe ademas crear la estructura para el caso de promosion, de acuerdo a la configuracion
                        //de la obra

                        if (presupuesto.Obra.TipoObra.bitSameEstructura.Value)
                        {
                            //procesa solo una vez, 
                            //para el caso de desaprobar no debe eliminar cada estrcutura),

                            foreach (var item in presupuesto.Partidas)
                            {
                                EstructuraCosto nuevo = new EstructuraCosto();
                                //por ser gastos , tambine deben poder emitir ordenes de compra
                                nuevo.SetAdd(_db, item.descripcion, presupuesto.idObra.Value, idEmpleado, 4,false);
                                _db.SubmitChanges();
                                //agregamos sus recursos
                                foreach (var recurso in item.Recursos)
                                {
                                    EstructuraCostoItem ecItem = new EstructuraCostoItem();
                                    ecItem.addECItemFromRecurso(_db, nuevo.idInternal, recurso, idEmpleado);
                                    recurso.updateUso(_db);
                                }
                                _db.SubmitChanges();
                                nuevo.updateMontoMonBase(_db);
                            }
                        }


                    }



                    result = true;
                }
                ts.Complete();
            }
            return result;
        }
        
        
        public bool updateDesAprobacion(int idPresupuesto)
        {
            //el presupuesto es el  debe de estar  generado
            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {
                    int idEmpleadoAprobacion = int.Parse(HttpContext.Current.Session["idEmpleado"].ToString());
                    //int idRol = int.Parse(HttpContext.Current.Session["idrol"].ToString());

                    Presupuesto presupuesto = _db.Presupuesto.Single(p => p.idInternal == idPresupuesto);
                    var empleadoobra = from a in _db.EmpleadoObras
                                       where a.idEmpleado == idEmpleadoAprobacion &
                                       a.idObra == presupuesto.idObra
                                       select a;

                    if (empleadoobra.Count() == 0)
                    {
                        throw new Exception("No tiene acceso a la obra ingresada");
                    }

                    Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == empleadoobra.First().idRol);
                    // paralos de menor nivel
                    //obtener el mayor permiso
                    if (rolEmpleado.nivelPrespuesto == 0)
                    {
                        throw new Exception("No puede Desaprobar Presupuesto");
                    }
                    if (presupuesto.idEstado!=25 & presupuesto.idEstado!=26)
                    {
                        throw new Exception("El documento no puede ser Desaprobado");
                    }

                    if (rolEmpleado.nivelPrespuesto==2)
                    {
                        // puede desaprobar los de nivel 2  y nivel 1
                        if (presupuesto.idEstado==26)
                        {
                            //segun presupuesto nivel1 o nivel2  actual
                            var q = from a in _db.Presupuesto
                                    where a.idPadre == idPresupuesto
                                    select a;
                            if (q.Count() > 0)
                            {
                                throw new Exception("Elimine el Presupuesto adicional");
                            }

                            // no debe existir E/C
                            var qq = from a in _db.EstructuraCostoItems
                                    where a.Recurso.Partida.idPresupuesto == idPresupuesto
                                    select a;

                            if (qq.Count() > 0 & presupuesto.Obra.TipoObra.bitSameEstructura.Value)
                            {
                                throw new Exception("Elimine las estructura del presupuesto ");
                            }
                            // de desaprueba completamente
                            presupuesto.updateDesaprobarAutorizado(_db);
                           
                            
                        }
                        if (presupuesto.idEstado==25)
                        {
                            presupuesto.updateDesaprobarRevisor(_db);

                        }

                    }
                    if (rolEmpleado.nivelPrespuesto == 1)
                    {
                        //solo nivel 1
                        if (presupuesto.idEstado == 25)
                        {
                            // de desaprueba completamente
                            presupuesto.updateDesaprobarRevisor(_db);
                            //this.delete(presuAdic.idInternal);
                            result = true;
                            
                        }
                        else
                        {
                            throw new Exception("No tiene acceso a Desaprobar, Requiere nivel 2");
                        }
                        

                    }
                   

                   
                }
                ts.Complete();
            }
            return result;
        }

 
        public bool delete(int idPresupuesto)
        {
            dbGestionDataContext _db;
            bool result = false;
            try
            {
                _db = new dbGestionDataContext(Parametros.strConnString);
                using (TransactionScope ts = new TransactionScope())
                {
                    Presupuesto presupuesto = _db.Presupuesto.Single(p => p.idInternal == idPresupuesto);
                    int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                    //--------------------
                    bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                        idEmpleadoEmisor,
                        1,
                        presupuesto.idObra.Value,
                        4); //total
                    //-------------------------   


                    var des = from b in _db.Recursos
                              where b.Partida.SubPresupuesto.idPresupuesto == idPresupuesto & b.parcialUso>0
                              select b;

                    if (des.Count() > 0)
                    {
                        throw new Exception("Existe recursos en uso, verifique");
                    }

                    var list=_db.SubPresupuesto.Where(p=>p.idPresupuesto==idPresupuesto);


                    foreach (var subPresupuesto in list)
                    {

                        var PartidaList = from a in _db.Partidas
                                          where a.idSubPresupuesto == subPresupuesto.idInternal
                                          select a;
                        foreach (Partida partida in PartidaList)
                        {

                            Rendimiento rendimiento = _db.Rendimiento.Single(p => p.idPartida == partida.idInternal);

                            
                            
                            var RecursoList = from a in _db.Recursos
                                              where a.idPartida == partida.idInternal
                                              select a;

                            _db.Recursos.DeleteAllOnSubmit(RecursoList);
                            _db.Rendimiento.DeleteOnSubmit(rendimiento);


                        }

                        _db.Partidas.DeleteAllOnSubmit(PartidaList);
                        _db.SubPresupuesto.DeleteOnSubmit(subPresupuesto);
                       
                    }
                    _db.Presupuesto.DeleteOnSubmit(presupuesto);
                    //ELIMINANOS DE LAS TAREAS PENDIENTES

                    var ww = from a in _db.TaskProceso
                             where a.idPresupuesto == idPresupuesto
                             select a;
                    if (ww.Count() > 0)
                    {
                        _db.TaskProceso.DeleteOnSubmit(ww.First());
                    }
                    _db.SubmitChanges();
                    ts.Complete();
                    result = true;
                }
                return result;
            }
            catch (Exception ex)
            {

                throw ex;
            }
            finally
            {
                _db = null;
            }
        }



        public void addFromExcel(string archivo,
                                    string nombre,
                                    string abreviacion,
                                    int idObra,
                                    int idMoneda,
                                    decimal tipoCambio
                                    )
        {

            int idEmpleado= int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {

                Presupuesto presupuesto = new Presupuesto();
                ;
                
                
                presupuesto.Add(_db,
                                "Load...",
                                nombre,
                                nombre,
                                abreviacion,
                                DateTime.Now,
                                idEmpleado,
                                idObra,
                                idMoneda,
                                tipoCambio,
                                1,
                                24,
                                Path.GetFileName(archivo)); 
                
                TaskProceso taskProceso = new TaskProceso();
                            taskProceso.Add(_db,
                                            "Importar PRespuesto " + Path.GetFileName(archivo),
                                            idObra,
                                            idEmpleado,
                                            19,// tarea de carga de presupuesto
                                            presupuesto.idInternal);


            }
            
            
            

        }

        public bool ExisteUsoRecurso(dbGestionDataContext _db, int idRecurso)
        {
            bool result = false;

            var qq= from a in _db.Recursos
                   where a.idInternal == idRecurso
                       select a;
            if (qq.Count() > 0)
            {
                Recurso Recurso = _db.Recursos.Single(p => p.idInternal == idRecurso);


                if (Recurso.bitsel == false)
                {
                    throw new Exception("El recurso  se encuentra Partido");
                }


                var q = from a in _db.EstructuraCostoItems
                        where a.idRecurso == idRecurso
                        select a;
                if (q.Count() > 0)
                {
                    result = true;
                    throw new Exception("El recurso  se encuentra  Utilizado");
                }
            }

            return result;
        }

        public bool verificarusoPartida(dbGestionDataContext _db, int idPartida)
        {
            bool result = true;


            var q = from a in _db.EstructuraCostoItems
                    where a.Recurso.idPartida == idPartida
                    select a;
            if (q.Count() > 0)
            {
                result = false;
                throw new Exception("No puede Elimiar Partida existe Recursos que estan siendo Utilizado");
            }


            return result;
        }
           
        public int partirRecurso(int idEstructuraCostoitem,List<EstructuraCostoitemsingleInfo> recursoList)
        {

            int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                   //verificamos la sumatoria de recursos
            decimal w = 0;
            decimal c = 0;
            var qq = from a in recursoList
                    select a;

            if (qq.Count() > 0)
            {
                 w = qq.Sum(p => p.total);
                 c = qq.Sum(p => p.cantidad);
            }
            else
            {
                throw new Exception("No exite registro de Insumos Configudos, verifique");
            }



                   dbGestionDataContext _db =
                        new dbGestionDataContext(Parametros.strConnString);



            //Estructura CostoItem

                   var qeci = from a in _db.ComparativoItems
                           where a.idEstructuraCostoItem == idEstructuraCostoitem
                           select a;
            if (qeci.Count()> 0)
            {
                throw new Exception("El recurso se encuetra utilizado en el comparativo");
            }
              EstructuraCostoItem ECItem= 
                                    ECItem=_db.EstructuraCostoItems.Single(p=>p.idInternal==idEstructuraCostoitem);
              

                //Recurso Padre
                Recurso dbRecurso= _db.Recursos.Single(p=>p.idInternal==ECItem.idRecurso);
            

               

                   using (TransactionScope ts = new TransactionScope())
                   {

                       foreach (EstructuraCostoitemsingleInfo recuitem in recursoList)
                                {
                                    if (recuitem.idInternal == 0)
                                    {
                                        continue;
                                    }
                                    Recurso item= new Recurso();


                                    item.Add(_db,
                                        dbRecurso.idInsumo.Value,
                                        dbRecurso.codigo,
                                        dbRecurso.descripcion,
                                        dbRecurso.unidad,
                                        dbRecurso.cuadrilla,
                                        recuitem.cantidad,
                                        dbRecurso.precio.Value,
                                        recuitem.total,
                                        dbRecurso.idPartida.Value,
                                        dbRecurso.grupo,
                                        dbRecurso.nivel.Value + 1,
                                        dbRecurso.idInternal
                                        );

                                }

                int i=ECItem.idEstructuraCosto.Value;
                _db.EstructuraCostoItems.DeleteOnSubmit(ECItem);
                _db.SubmitChanges();

                dbRecurso.updateUso(_db);
                dbRecurso.bitsel=false;

                if (dbRecurso.parcialUso.Value - dbRecurso.parcial.Value > 0)
                {
                    throw new Exception("Monto ingresado es diferente  al permitido");
                }

                //parte del proceso este  recursos seran retirado de la ECostoitem

              

                _db.SubmitChanges();

                // como se elimino de la estructura  se actualiza el total
                EstructuraCosto EC = _db.EstructuraCostos.Single(p=>p.idInternal==i);
                EC.updateMontoMonBase(_db);
             

                    ts.Complete();
            }
                   return dbRecurso.idInternal;                 
             
            }
        public bool juntarRecurso(int idPadre)
        {
            bool result;

            dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString);
            //RecursoPadre
            Recurso recurso = _db.Recursos.Single(p => p.idInternal == idPadre);
            
            var q=  from a in _db.Recursos
                    where a.idPadre == idPadre
                    select a;
            // es importante que todos los hijos esten liberados para eliminarlos
            foreach (Recurso recu in q)
            {
                if (recu.parcialUso > 0)
                {
                    throw new Exception("Los recursos partidos se encuentran en uso");

                }

            }

            // eliminamos los recursos
            _db.Recursos.DeleteAllOnSubmit(q);
            recurso.bitsel = true;
            recurso.updateUso(_db);
            

            using (TransactionScope ts = new TransactionScope())
            {
                _db.SubmitChanges();
                ts.Complete();
                result = true;
            }
            return result;

        }
 #endregion

        #region "Load"


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<PartidadEditInfo> getListPartida(int idPresupuesto)
        {

            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {

                var q = (from a in _db.Rendimiento
                        where a.Partida.SubPresupuesto.idPresupuesto == idPresupuesto
                        select new PartidadEditInfo
                        {
                            idInternal = a.Partida.idInternal,
                            idRendimiento = a.idInternal,
                            codigo = a.Partida.codigo,
                            descripcion = a.Partida.descripcion,
                            simbol=a.Partida.Presupuesto.Moneda.simbol,
                            rendimiento = a.descripcion,
                            valor = a.eqValor,
                            EQ = a.EQ,
                            eqValor = a.eqValor.Value,
                            costoAfecMetrado = a.costoAfecMetrado.Value,
                            
                            monto = a.Partida.Recursos.Count() > 0 ? a.Partida.Recursos.Where(o => o.nivel == 0).Sum(p => p.parcial).Value : 0,
                            montoUso=a.Partida.Recursos.Count==0?0:a.Partida.Recursos.Sum(p=>p.parcialUso).Value,
                            montoSaldo=(a.Partida.Recursos.Count() > 0 ? a.Partida.Recursos.Where(o => o.nivel == 0).Sum(p => p.parcial).Value : 0)-
                                        (a.Partida.Recursos.Count==0?0:a.Partida.Recursos.Sum(p=>p.parcialUso).Value),

                        }).OrderBy(p=>p.codigo);

                return q.ToList();




            }

        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public PresupuestoEditInfo loadPresupuestoAdicional(int idPresupuesto)
        {

            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {

                var q = from a in _db.Presupuesto
                        where a.idInternal == idPresupuesto
                        select new PresupuestoEditInfo
                        {
                            idInternal=a.idInternal,
                            codigo=a.codigo,
                            descripcion=a.descripcion,
                            nombre=a.nombre,
                            abreviacion=a.abreviacion,
                            fecha=a.fecha.Value,
                            FechaCreacion=a.fechaCre.Value,
                            FechaModificacion=a.fechaMod.Value,
                            moneda=a.Moneda.descripcion,
                            monto=a.monto.Value,
                           tipoCambio=a.Obra.tipoCambio.Value,
                            tipoCambioContrato=a.Obra.tipoCambio.Value,
                            tipoOrigen=a.tipoOrigen.Value,
                            Estado=a.GrupoDatoitem.descripcion,
                            aprobador1=a.Empleado1.descripcion,
                            aprobador2=a.Empleado.descripcion,
                            archivo=a.archivo,
                            idEstado=a.idEstado.Value,
                            simbolMoneda=a.Moneda.simbol
                            // el orden segun las columans 
                        };

                return q.First();




            }

        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public PartidadEditInfo loadPartida(int idPartida)
        {

            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {
                PartidadEditInfo partida= new PartidadEditInfo();

                var q = from a in _db.Rendimiento
                        where a.Partida.idInternal == idPartida
                        select new PartidadEditInfo
                        {
                            idInternal = a.Partida.idInternal,
                            codigo = a.Partida.codigo,
                            descripcion = a.descripcion,
                            idRendimiento = a.idInternal,
                            monto = a.monto.Value,
                            rendimiento = a.descripcion,
                            valor = a.eqValor.Value,
                            EQ=a.EQ,
                            eqValor=a.eqValor.Value,
                            costoAfecMetrado = a.costoAfecMetrado.Value
                        };
                if (q.Count() > 0)
                {
                    partida = q.First();
                }

                return partida;




            }

        }
        
        #region "get Presu"



        int _count;
         public int Count(int idObra, DateTime fechaInicio, DateTime fechaFin, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }


         private IQueryable<PresupuestoListInfo> ApplySort(IQueryable<PresupuestoListInfo> q, string sortExpression)
         {
             switch (sortExpression)
             {
                 case "abreviacion":
                     q = q.OrderBy(b => b.abreviacion);
                     break;
                 case "abreviacion DESC":
                     q = q.OrderByDescending(b => b.abreviacion);
                     break;
                 case "adicionales":
                     q = q.OrderBy(b => b.adicionales);
                     break;
                 case "adicionales DESC":
                     q = q.OrderByDescending(b => b.adicionales);
                     break;
                 case "codigo":
                     q = q.OrderBy(b => b.codigo);
                     break;
                 case "codigo DESC":
                     q = q.OrderByDescending(b => b.codigo);
                     break;

                 case "estado":
                     q = q.OrderBy(b => b.estado);
                     break;
                 case "estado DESC":
                     q = q.OrderByDescending(b => b.estado);
                     break;


                 case "fechaCre":
                     q = q.OrderBy(b => b.fechaCre);
                     break;
                 case "fechaCre DESC":
                     q = q.OrderByDescending(b => b.fechaCre);
                     break;


                 case "monto":
                     q = q.OrderBy(b => b.monto);
                     break;
                 case "monto DESC":
                     q = q.OrderByDescending(b => b.monto);
                     break;
                 case "montoAddSimbol":
                     q = q.OrderBy(b => b.montoAddSimbol);
                     break;
                 case "montoAddSimbol DESC":
                     q = q.OrderByDescending(b => b.montoAddSimbol);
                     break;

                 case "montoadicionales":
                     q = q.OrderBy(b => b.montoadicionales);
                     break;
                 case "montoadicionales DESC":
                     q = q.OrderByDescending(b => b.montoadicionales);
                     break;

                 case "montoSimbol":
                     q = q.OrderBy(b => b.montoSimbol);
                     break;
                 case "montoSimbol DESC":
                     q = q.OrderByDescending(b => b.montoSimbol);
                     break;

                 case "saldo":
                     q = q.OrderBy(b => b.saldo);
                     break;
                 case "saldo DESC":
                     q = q.OrderByDescending(b => b.monto);
                     break;

                 case "nombre":
                     q = q.OrderBy(b => b.nombre);
                     break;
                 case "nombre DESC":
                     q = q.OrderByDescending(b => b.nombre);
                     break;


                 case "tipoOrigen":
                     q = q.OrderBy(b => b.tipoOrigen);
                     break;
                 case "tipoOrigen DESC":
                     q = q.OrderByDescending(b => b.tipoOrigen);
                     break;


                 
                 default:
                     q = q.OrderByDescending(b => b.fechaCre);
                     break;
             }
             return q;
         }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
         public IEnumerable<PresupuestoListInfo> getPresupuestoList(int idObra, DateTime fechaInicio, DateTime fechaFin, int startRowIndex, int maximumRows, string sortExpression)
        {

          

                var q = (from a in DbUtil.Db.Presupuesto
                         join b in DbUtil.Db.Presupuesto on a.idInternal equals b.idPadre into viewpresu
                         from c in viewpresu.DefaultIfEmpty()
                         where a.idObra == idObra & a.tipoOrigen == 1 //No adiconales 
                           & a.fechaCre > fechaInicio & a.fechaCre < fechaFin.AddDays(1)
                         select new PresupuestoListInfo
                        {
                            idInternal = a.idInternal,
                            abreviacion = a.abreviacion,
                            adicionales = (c.nombre==null?"":c.nombre),
                            idPresupuestoHijo = (c.idInternal == null ? 0 : c.idInternal),
                            montoadicionales = c.monto,
                            montoAddSimbol = String.Format("{0} {1:N}", c.Moneda.simbol, c.monto),
                            codigo = a.codigo,
                            estado = a.GrupoDatoitem.descripcion,
                            fechaCre = a.fechaCre.Value,
                            fechaCreStr = a.fechaCre.Value.ToShortDateString(),
                            idObra = a.idObra.Value,
                            nombre = a.nombre,
                            tipoOrigen = a.tipoOrigen.Value,
                            monto=a.monto.Value,
                            montoUso=a.Partidas.Count==0?0:a.Partidas.Sum(p=>(p.Recursos.Count()>0)?p.Recursos.Sum(w=>w.parcialUso.Value):0  ),
                            saldo=a.monto.Value-(a.Partidas.Count==0?0:a.Partidas.Sum(p=>(p.Recursos.Count()>0)?p.Recursos.Sum(w=>w.parcialUso.Value):0  )),
                            simbol=a.Moneda.simbol,
                            
                        });



                _count = q.Count();
                q = ApplySort(q, sortExpression);
                return q.Skip(startRowIndex).Take(maximumRows);



        }
        #endregion

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<RecursoEditInfo> getListRecurso(int idPartida)
        {
                List<RecursoEditInfo> lista = new List<RecursoEditInfo>();
                var q = (from a in  DbUtil.Db.Recursos
                         join b in DbUtil.Db.EstructuraCostoItems on a.idInternal equals b.idRecurso into viewrecurso
                         from c in viewrecurso.DefaultIfEmpty()
                         where a.idPartida == idPartida & a.nivel == 0
                        select new RecursoEditInfo
                        {
                            idInternal =a.idInternal,
                            idInsumo=a.idInsumo.Value,
                            codigo =a.codigo,
                            descripcion =a.descripcion,
                            unidad =a.unidad,
                            cuadrilla =a.cuadrilla,
                            cantidad =a.cantidad.Value,
                            precio =a.precio.Value,
                            parcial =a.parcial.Value,
                            idObra=a.Partida.SubPresupuesto.Presupuesto.idObra.Value,
                            bitsel=a.bitsel.Value,
                            idEstructuraCosto=(c.idEstructuraCosto==null)?0:c.idEstructuraCosto,
                            parcialUso=a.parcialUso.Value,
                            rutaUsoStr = (c.idEstructuraCosto == null) ? "" : string.Format("~/ObraAdmin/EstructuraCompras/EstructuraCostoEditForm.aspx?id={0}&idObra={1}", c.idEstructuraCosto, c.EstructuraCosto.idObra),
                            UsoECStr=(a.Recursos.Count>0)?"R Partido":string.Format("{0:N}",a.parcialUso.Value),
                            idPartida =a.idPartida.Value,
                            ECstr=a.EstructuraCostoItems.Count()>0?a.EstructuraCostoItems.First().EstructuraCosto.descripcion:"",
                        
                        }).Distinct().OrderBy(p=>p.idInternal);
        
            
                if (q.Count() >= 0)
                {
                    lista=q.ToList();
                }
                        return lista;




        

        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<RecursoEditInfo> getListRecursoFromPresup(int idPresupuesto)
        {

            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {

                var q = from a in _db.Recursos
                        where a.Partida.SubPresupuesto.idPresupuesto == idPresupuesto 
                        & a.nivel==0
                        select new RecursoEditInfo
                        {
                            idInternal = a.idInternal,
                            idInsumo=a.idInsumo.Value,
                            codigo = a.codigo,
                            descripcion = a.descripcion,
                            unidad = a.unidad,
                            cuadrilla = a.cuadrilla,
                            cantidad = a.cantidad.Value,
                            precio = a.precio.Value,
                            parcial = a.parcial.Value,
                            bitsel = a.bitsel.Value,
                            idObra=a.Partida.SubPresupuesto.Presupuesto.idObra.Value,
                            idPartida = a.idPartida.Value
                        };
                return q.ToList();
}

        }


        #endregion

        //#region GET
        
        


        //int _count;
        //public int Count(int idObra, int startRowIndex, int maximumRows, string sortExpression)
        //{
        //    return _count;
        //}
        //public int Count(int startRowIndex, int maximumRows, string sortExpression, int idAlmacen)
        //{
        //    return _count;
        //}


        //private IQueryable<OrdenCompraListInfo> ApplySort(IQueryable<OrdenCompraListInfo> q, string sortExpression)
        //{
        //    switch (sortExpression)
        //    {
        //        case "numDocumento":
        //            q = q.OrderBy(b => b.numDocumento);
        //            break;
        //        case "numDocumento DESC":
        //            q = q.OrderByDescending(b => b.numDocumento);
        //            break;
        //        case "fechaEmision":
        //            q = q.OrderBy(b => b.fechaEmision);
        //            break;
        //        case "fechaEmision DESC":
        //            q = q.OrderByDescending(b => b.fechaEmision);
        //            break;
        //        case "proveedor":
        //            q = q.OrderBy(b => b.proveedor);
        //            break;
        //        case "proveedor DESC":
        //            q = q.OrderByDescending(b => b.proveedor);
        //            break;

        //        case "subTotal":
        //            q = q.OrderBy(b => b.subTotal);
        //            break;
        //        case "subTotal DESC":
        //            q = q.OrderByDescending(b => b.subTotal);
        //            break;


        //        case "IGVTotal":
        //            q = q.OrderBy(b => b.IGVTotal);
        //            break;
        //        case "IGVTotal DESC":
        //            q = q.OrderByDescending(b => b.IGVTotal);
        //            break;


        //        case "total":
        //            q = q.OrderBy(b => b.total);
        //            break;
        //        case "total DESC":
        //            q = q.OrderByDescending(b => b.total);
        //            break;
        //        case "condicion":
        //            q = q.OrderBy(b => b.condicion);
        //            break;
        //        case "condicion DESC":
        //            q = q.OrderByDescending(b => b.condicion);
        //            break;

        //    }
        //    return q;
        //}

        ///// <summary>
        ///// Ordenes de Compra pendientes de Facturar
        ///// solo los que tengan el ingreso completo en  Almacen
        ///// </summary>
        ///// <param name="idObra"></param>
        ///// <param name="startRowIndex"></param>
        ///// <param name="maximumRows"></param>
        ///// <param name="sortExpression"></param>
        ///// <returns></returns>

        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public IEnumerable<OrdenCompraListInfo> getOrdenCompraSinFactura(int idObra, int startRowIndex, int maximumRows, string sortExpression)
        //{




        //    var q2 = from a in DbUtil.Db.OrdenCompras
        //             where a.idObra == idObra
        //             & a.OrdenCompraItems.Sum(p => p.cantidad) == a.OrdenCompraItems.Sum(p => p.cantidadRecep)
        //             select new OrdenCompraListInfo
        //             {
        //                 idInternal = a.idInternal,
        //                 proveedor = a.ComparativoProveedor.Proveedor.descripcion.ToUpper(),
        //                 atencionEntrega = a.atencionEntrega,
        //                 autorizado = a.autorizado,
        //                 bitActivo = a.bitActivo.Value,
        //                 bitInclIGV = a.bitInclIGV.Value,
        //                 centroCosto = a.centroCosto,
        //                 contacProveedor = a.contacProveedor,
        //                 desComparativo = a.Comparativo.descripcion,
        //                 direccionEntComprobante = a.direccionEntComprobante,
        //                 direccionEntrega = a.direccionEntrega,
        //                 emisor = a.emisor,
        //                 estado = a.GrupoDatoitem.descripcion,
        //                 estructura = a.estructura,
        //                 fechaAnula = a.fechaAnula,
        //                 //fechaContrato = a.fechaContrato.Value,
        //                 fechaCre = a.fechaCre.Value,
        //                 fechaEmision = a.fechaEmision.Value,
        //                 fechaMod = a.fechaMod.Value,
        //                 fechaEntrega = a.fechaPedido,
        //                 formaPago = a.FormaPago.descripcion,
        //                 idComparativo = a.idComparativo.Value,
        //                 idEstado = a.idEstado.Value,
        //                 idEstructura = a.idEstructura.Value,
        //                 idFormaPago = a.idFormaPago.Value,
        //                 idMoneda = a.idMoneda.Value,
        //                 idObra = a.idObra.Value,
        //                 idProveedor = a.idProveedor.Value,
        //                 idProveedorSelec = a.idProveedorSelec.Value,
        //                 idUsuarioAnula = a.idUsuarioAnula,
        //                 IGV = a.igv.Value,//(a.igv*100).Value.ToString("N"),
        //                 IGVTotal = a.IGVTotal.Value,
        //                 moneda = a.moneda,
        //                 numComparativo = a.Comparativo.numDocumento,
        //                 numDocumento = a.numDocumento,
        //                 observaciones = a.observaciones,
        //                 simbol = a.Moneda1.simbol,
        //                 subTotal = a.subTotal.Value,
        //                 tipoCambio = a.tipoCambio.Value,
        //                 total = a.total.Value,
        //                 UsuarioCre = a.UsuarioCre.Value,
        //                 UsuarioMod = a.UsuarioMod.Value
        //             };
        //    _count = q2.Count();
        //    q2 = ApplySort(q2, sortExpression);
        //    return q2.Skip(startRowIndex).Take(maximumRows);



        //}


        ///// <summary>
        ///// Ordenes de Compra pendientes de Aprobacion 
        ///// </summary>
        ///// <param name="idObra"></param>
        ///// <param name="startRowIndex"></param>
        ///// <param name="maximumRows"></param>
        ///// <param name="sortExpression"></param>
        ///// <returns></returns>

        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public IEnumerable<OrdenCompraListInfo> getOrdenCompraSinAprobar(int idObra, int startRowIndex, int maximumRows, string sortExpression)
        //{
        //    var q2 = from a in DbUtil.Db.OrdenCompras
        //             where a.idObra == idObra
        //             & a.idEstado == 11
        //             select new OrdenCompraListInfo
        //             {
        //                 idInternal = a.idInternal,
        //                 proveedor = a.ComparativoProveedor.Proveedor.descripcion.ToUpper(),
        //                 atencionEntrega = a.atencionEntrega,
        //                 autorizado = a.autorizado,
        //                 bitActivo = a.bitActivo.Value,
        //                 bitInclIGV = a.bitInclIGV.Value,
        //                 centroCosto = a.centroCosto,
        //                 contacProveedor = a.contacProveedor,
        //                 desComparativo = a.Comparativo.descripcion,
        //                 direccionEntComprobante = a.direccionEntComprobante,
        //                 direccionEntrega = a.direccionEntrega,
        //                 emisor = a.emisor,
        //                 estado = a.GrupoDatoitem.descripcion,
        //                 estructura = a.estructura,
        //                 fechaAnula = a.fechaAnula,
        //                 //fechaContrato = a.fechaContrato.Value,
        //                 fechaCre = a.fechaCre.Value,
        //                 fechaEmision = a.fechaEmision.Value,
        //                 fechaMod = a.fechaMod.Value,
        //                 fechaEntrega = a.fechaPedido,
        //                 formaPago = a.FormaPago.descripcion,
        //                 idComparativo = a.idComparativo.Value,
        //                 idEstado = a.idEstado.Value,
        //                 idEstructura = a.idEstructura.Value,
        //                 idFormaPago = a.idFormaPago.Value,
        //                 idMoneda = a.idMoneda.Value,
        //                 idObra = a.idObra.Value,
        //                 idProveedor = a.idProveedor.Value,
        //                 idProveedorSelec = a.idProveedorSelec.Value,
        //                 idUsuarioAnula = a.idUsuarioAnula,
        //                 IGV = a.igv.Value,//(a.igv*100).Value.ToString("N"),
        //                 IGVTotal = a.IGVTotal.Value,
        //                 moneda = a.moneda,
        //                 numComparativo = a.Comparativo.numDocumento,
        //                 numDocumento = a.numDocumento,
        //                 observaciones = a.observaciones,
        //                 simbol = a.Moneda1.simbol,
        //                 subTotal = a.subTotal.Value,
        //                 tipoCambio = a.tipoCambio.Value,
        //                 total = a.total.Value,
        //                 UsuarioCre = a.UsuarioCre.Value,
        //                 UsuarioMod = a.UsuarioMod.Value
        //             };
        //    _count = q2.Count();
        //    q2 = ApplySort(q2, sortExpression);
        //    return q2.Skip(startRowIndex).Take(maximumRows);



        //}



        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public List<OrdenCompraListInfo> getOrdenCompraSinFactura(int idObra)
        //{


        //    var q2 = from a in DbUtil.Db.OrdenCompras
        //             where a.idObra == idObra & a.idEstado == 13 //
        //             select new OrdenCompraListInfo
        //             {
        //                 idInternal = a.idInternal,
        //                 proveedor = a.ComparativoProveedor.Proveedor.descripcion.ToUpper(),
        //                 atencionEntrega = a.atencionEntrega,
        //                 autorizado = a.autorizado,
        //                 bitActivo = a.bitActivo.Value,
        //                 bitInclIGV = a.bitInclIGV.Value,
        //                 centroCosto = a.centroCosto,
        //                 contacProveedor = a.contacProveedor,
        //                 desComparativo = a.Comparativo.descripcion,
        //                 direccionEntComprobante = a.direccionEntComprobante,
        //                 direccionEntrega = a.direccionEntrega,
        //                 emisor = a.emisor,
        //                 estado = a.GrupoDatoitem.descripcion,
        //                 estructura = a.estructura,
        //                 fechaAnula = a.fechaAnula,
        //                 //fechaContrato = a.fechaContrato.Value,
        //                 fechaCre = a.fechaCre.Value,
        //                 fechaEmision = a.fechaEmision.Value,
        //                 fechaMod = a.fechaMod.Value,
        //                 fechaEntrega = a.fechaPedido,
        //                 formaPago = a.FormaPago.descripcion,
        //                 idComparativo = a.idComparativo.Value,
        //                 idEstado = a.idEstado.Value,
        //                 idEstructura = a.idEstructura.Value,
        //                 idFormaPago = a.idFormaPago.Value,
        //                 idMoneda = a.idMoneda.Value,
        //                 idObra = a.idObra.Value,
        //                 idProveedor = a.idProveedor.Value,
        //                 idProveedorSelec = a.idProveedorSelec.Value,
        //                 idUsuarioAnula = a.idUsuarioAnula,
        //                 IGV = a.igv.Value,//(a.igv*100).Value.ToString("N"),
        //                 IGVTotal = a.IGVTotal.Value,
        //                 moneda = a.moneda,
        //                 numComparativo = a.Comparativo.numDocumento,
        //                 numDocumento = a.numDocumento,
        //                 observaciones = a.observaciones,
        //                 simbol = a.Moneda1.simbol,
        //                 subTotal = a.subTotal.Value,
        //                 tipoCambio = a.tipoCambio.Value,
        //                 total = a.total.Value,
        //                 UsuarioCre = a.UsuarioCre.Value,
        //                 UsuarioMod = a.UsuarioMod.Value
        //             };

        //    return q2.ToList();



        //}



        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public List<OrdenCompraListInfo> getOrdenCompraList(int idObra, DateTime inicio, DateTime fin)
        //{

        //    var q2 = from a in DbUtil.Db.OrdenCompras
        //             orderby a.numDocumento
        //             where a.idObra == idObra
        //             select new OrdenCompraListInfo
        //             {
        //                 idInternal = a.idInternal,
        //                 proveedor = a.ComparativoProveedor.Proveedor.descripcion.ToUpper(),
        //                 atencionEntrega = a.atencionEntrega,
        //                 autorizado = a.autorizado,
        //                 bitActivo = a.bitActivo.Value,
        //                 bitInclIGV = a.bitInclIGV.Value,
        //                 centroCosto = a.centroCosto,
        //                 contacProveedor = a.contacProveedor,
        //                 desComparativo = a.Comparativo.descripcion,
        //                 direccionEntComprobante = a.direccionEntComprobante,
        //                 direccionEntrega = a.direccionEntrega,
        //                 emisor = a.emisor,
        //                 estado = a.GrupoDatoitem.descripcion,
        //                 estructura = a.estructura,
        //                 fechaAnula = a.fechaAnula,
        //                 //fechaContrato = a.fechaContrato.Value,
        //                 fechaCre = a.fechaCre.Value,
        //                 fechaEmision = a.fechaEmision.Value,
        //                 fechaMod = a.fechaMod.Value,
        //                 fechaEntrega = a.fechaPedido,
        //                 formaPago = a.FormaPago.descripcion,
        //                 idComparativo = a.idComparativo.Value,
        //                 idEstado = a.idEstado.Value,
        //                 idEstructura = a.idEstructura.Value,
        //                 idFormaPago = a.idFormaPago.Value,
        //                 idMoneda = a.idMoneda.Value,
        //                 idObra = a.idObra.Value,
        //                 idProveedor = a.idProveedor.Value,
        //                 idProveedorSelec = a.idProveedorSelec.Value,
        //                 idUsuarioAnula = a.idUsuarioAnula,
        //                 IGV = a.igv.Value,
        //                 IGVTotal = a.IGVTotal.Value,
        //                 moneda = a.moneda,
        //                 numComparativo = a.Comparativo.numDocumento,
        //                 numDocumento = a.numDocumento,
        //                 observaciones = a.observaciones,
        //                 simbol = a.Moneda1.simbol,
        //                 subTotal = a.subTotal.Value,
        //                 tipoCambio = a.tipoCambio.Value,
        //                 total = a.total.Value,
        //                 UsuarioCre = a.UsuarioCre.Value,
        //                 UsuarioMod = a.UsuarioMod.Value
        //             };

        //    return q2.ToList();



        //}





        //#endregion


        private List<int> listaRecursosHijos(int idrecurso)
        {
            List<int> lista= new List<int>();
            List<int> listaHijos= new List<int>();
            var recurso2 = from a in DbUtil.Db.Recursos
                           where a.idPadre == idrecurso
                           select a;

            foreach (var item in recurso2)
                {
                lista.Add(item.idInternal);
                 if (!item.bitsel.Value)
                    {
                        listaHijos = this.listaRecursosHijos(item.idInternal);
                     }
                lista.AddRange(listaHijos);
            }

            return lista;
        }
        
        public List<RecursoUsoInfo> GetListaPartidos(int idRecurso)
        {
            //var recurso = DbUtil.Db.Recursos.Single(p => p.idInternal == idRecurso);
            
            var h=this.listaRecursosHijos(idRecurso);

             
                         //left join
            var q= from a in DbUtil.Db.Recursos
                   join b in DbUtil.Db.EstructuraCostoItems on a.idInternal equals b.idRecurso into viewecitem
                   from c in viewecitem.DefaultIfEmpty()
                   where h.Contains(a.idInternal)
                   select  new RecursoUsoInfo
                   {
                       idpadre = a.idPadre.Value,
                       idInternal=a.idInternal,
                       total=String.Format("{0}{1:N}",a.Partida.Presupuesto.Moneda.simbol,a.parcial.Value),
                       totalUso=String.Format("{0}{1:N}",a.Partida.Presupuesto.Moneda.simbol,a.parcialUso.Value),
                     
                       EC=c.EstructuraCosto.descripcion
                       
                   };

            return q.ToList();
            

            }

        #region "Partida"
        public int AddPartida(dbGestionDataContext _db,
                               string descripcion,
                                int idPresupuesto)
        {
            using (TransactionScope ts = new TransactionScope())
            {

                SubPresupuesto subpre = _db.SubPresupuesto.Single(p => p.idPresupuesto == idPresupuesto);
                Partida partida = new Partida();

                partida.Add(_db,
                            partida.getCorrelativo(_db,idPresupuesto),
                            descripcion,
                            subpre.idInternal,
                            idPresupuesto);
                
                
                Rendimiento rendimiento = new Rendimiento();
                    rendimiento.Add(_db,
                                    "0",
                                    0,
                                    "0",
                                    0,
                                    0,
                                    partida.idInternal,
                                    rendimiento.GetMontoRecurso(_db, partida.idInternal));

                
                _db.SubmitChanges();
                ts.Complete();
                return partida.idInternal;
            }
        }

        public void UpdatePartida(dbGestionDataContext _db,
                            int idPartida,
                            string codigo,
                            string descripcion
                           )
        {
            using (TransactionScope ts = new TransactionScope())
            {

                Partida partida = _db.Partidas.Single(p => p.idInternal == idPartida);
                partida.descripcion = descripcion;
                partida.codigo = codigo;


                Rendimiento rendimiento = new Rendimiento();
                rendimiento.monto = rendimiento.GetMontoRecurso(_db, partida.idInternal);

                Presupuesto presupuesto = _db.Presupuesto.Single(p => p.idInternal == partida.idPresupuesto);
                presupuesto.updateTotal(_db);
                _db.SubmitChanges();
                ts.Complete();
                
            }
        }

        public bool deletePartida(int idPartida)
        {
            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {
                    Partida partida = _db.Partidas.Single(p => p.idInternal == idPartida);

                    //el recurso no debe ser de tipo de presupuesto 1
                    //if (partida.SubPresupuesto.Presupuesto.tipoOrigen == 1)
                    //{
                    //    throw new Exception("El recurso no pude ser elimnado por ser cargado desde excel");
                    //}

                    //verificamos que no tenga uso


                    var q = from a in _db.Recursos
                            where a.idPartida == idPartida
                            select a;

                    if (q.Count() > 0)
                    {
                        throw new Exception("Existe dependencia de recursos,verifique Recurso");
                    }
                    _db.Rendimiento.DeleteAllOnSubmit(partida.Rendimientos);
                    _db.Partidas.DeleteOnSubmit(partida);
                    _db.SubmitChanges();
                    ts.Complete();
                    result = true;
                }
                return result;
            }


        }

        #endregion




#region "Recursos"      
        public int AddRecurso(dbGestionDataContext _db,
                   int idInsumo,
                   decimal cantidad,
                   decimal total, int idPartida)
        {
            using (TransactionScope ts = new TransactionScope())
            {

               // int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                Insumo insumo = _db.Insumos.Single(p => p.idInternal == idInsumo);
                Recurso recurso = new Recurso();

                recurso.Add(_db,
                    insumo.idInternal,
                    insumo.codigo,
                    insumo.descripcion,
                    insumo.InsumoUnidad.abreviacion,
                    0,
                    cantidad,
                    total / cantidad,
                    total,
                    idPartida,
                    27,
                    0,
                    null);
                //actualizar Partida
                Partida partida = _db.Partidas.Single(p => p.idInternal == idPartida);
               

                partida.Rendimientos.First().updateMonto(_db);
                               
                partida.Presupuesto.updateTotal(_db);
                
                _db.SubmitChanges();
                ts.Complete();
                return recurso.idInternal;
            }
        }

        public int UpdateRecurso(dbGestionDataContext _db,
                            int idrecurso,
                           decimal cantidad,
                           decimal total, int idPartida)
        {
            using (TransactionScope ts = new TransactionScope())
            {


                
                Recurso recurso = _db.Recursos.Single(p => p.idInternal == idrecurso);
                Insumo insumo=_db.Insumos.Single(p=>p.idInternal==recurso.idInsumo);
                if (!this.ExisteUsoRecurso(_db, recurso.idInternal))
                {
                    recurso.Update(_db,
                    insumo.idInternal,
                    insumo.codigo,
                    insumo.descripcion,
                    insumo.InsumoUnidad.abreviacion,
                    cantidad,
                    total / cantidad,
                    total,
                    0);
                }

                //actualizar Partida
                Partida partida = _db.Partidas.Single(p => p.idInternal == idPartida);
                partida.Rendimientos.First().updateMonto(_db);

                partida.Presupuesto.updateTotal(_db);
                
                _db.SubmitChanges();
                ts.Complete();
                return recurso.idInternal;
            }
        }

        public bool deleteRecurso(int idRecurso)
        {
            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {
                    Recurso recurso = _db.Recursos.Single(p => p.idInternal == idRecurso);

                    //el recurso no debe ser de tipo de presupuesto 1
                    //if (recurso.Partida.SubPresupuesto.Presupuesto.tipoOrigen == 1)
                    //{
                    //    throw new Exception("El recurso no pude ser elimnado por ser cargado desde excel");
                    //}

                    //verificamos que no tenga uso
                    int idpartida = recurso.idPartida.Value;

                    var q = from a in _db.Recursos
                            where a.idPadre == idRecurso
                            select a;

                    if (q.Count() > 0)
                    {
                        throw new Exception("Existe dependencia de recursos,verifique particiones");
                    }
                    if (recurso.parcialUso > 0)
                    {
                        throw new Exception("El recurso se encuentra utilizado,verifique Estructura de Compra");
                    }

                    _db.Recursos.DeleteOnSubmit(recurso);
                    _db.SubmitChanges();
                    //actualizar Partida
                    Partida partida = _db.Partidas.Single(p => p.idInternal == idpartida);

                    partida.Rendimientos.First().updateMonto(_db);
                    partida.Presupuesto.updateTotal(_db);


                    ts.Complete();
                    result = true;
                }
                return result;
            }


        }


#endregion


        #region "get Control Recursos"



        public int Count(int idPresupuesto, int idGrupo, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }

        private IQueryable<RecursoListInfo> ApplySort(IQueryable<RecursoListInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "desPresupuesto":
                    q = q.OrderBy(b => b.desPresupuesto);
                    break;
                case "desPresupuesto DESC":
                    q = q.OrderByDescending(b => b.desPresupuesto);
                    break;
                case "codPartida":
                    q = q.OrderBy(b => b.codPartida);
                    break;
                case "codPartida DESC":
                    q = q.OrderByDescending(b => b.codPartida);
                    break;
                case "desPartida":
                    q = q.OrderBy(b => b.desPartida);
                    break;
                case "desPartida DESC":
                    q = q.OrderByDescending(b => b.desPartida);
                    break;
                case "codigo":
                    q = q.OrderBy(b => b.codigo);
                    break;
                case "codigo DESC":
                    q = q.OrderByDescending(b => b.codigo);
                    break;

                case "descripcion":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;


                case "cantidad":
                    q = q.OrderBy(b => b.cantidad);
                    break;
                case "cantidad DESC":
                    q = q.OrderByDescending(b => b.cantidad);
                    break;

                case "parcial":
                    q = q.OrderBy(b => b.parcial);
                    break;
                case "parcial DESC":
                    q = q.OrderByDescending(b => b.parcial);
                    break;



                case "precio":
                    q = q.OrderBy(b => b.precio);
                    break;
                case "precio DESC":
                    q = q.OrderByDescending(b => b.precio);
                    break;
                
                default:
                    q = q.OrderBy(b => b.codPartida);
                    break;


            }
            return q;
        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<RecursoListInfo> getRecursosPresupuestoList(int idPresupuesto,int idgrupo=default(int),int nivelBusqueda=default(int), string valorStr=default(string), string sortExpression = default(string))
        {
            //nivelBusqueda == 0=>todos 
            //nivelBusqueda==  1=>partida
            //nivel 2=>Recurso

            var q = this.ApplySelect_RecursoListInfo();

            if (idgrupo!=0 & nivelBusqueda==0)
            {
                q = q.Where(i => (i.parcial - i.parcialUso) > 0
                      & i.idPresupuesto == idPresupuesto
                      & i.bitsel == true
                      & i.idgrupo == idgrupo);
            }

            if (nivelBusqueda == 1)
            {

                q = q.Where(i => (i.parcial - i.parcialUso) > 0
                        & i.idPresupuesto == idPresupuesto
                        & i.bitsel == true
                        & (i.codPartida + i.desPartida).Contains(valorStr));
            }
            if (nivelBusqueda == 2)
            {

                q = q.Where(i => (i.parcial - i.parcialUso) > 0
                        & i.idPresupuesto == idPresupuesto
                        & i.bitsel == true
                        & (i.codigo + i.descripcion).Contains(valorStr));
            }

            q = ApplySortG(q, sortExpression);


            return q.ToList();

        }
        private IQueryable<RecursoListInfo> ApplySortG(IQueryable<RecursoListInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "idInternal ASC":
                    q = q.OrderBy(b => b.idInternal);
                    break;
                case "idInternal DESC":
                    q = q.OrderByDescending(b => b.idInternal);
                    break;
                case "cantidad ASC":
                    q = q.OrderBy(b => b.cantidad);
                    break;
                case "cantidad DESC":
                    q = q.OrderByDescending(b => b.cantidad);
                    break;
                case "codigo ASC":
                    q = q.OrderBy(b => b.codigo);
                    break;
                case "codigo DESC":
                    q = q.OrderByDescending(b => b.codigo);
                    break;

                case "codPartida ASC":
                    q = q.OrderBy(b => b.codPartida);
                    break;
                case "codPartida DESC":
                    q = q.OrderByDescending(b => b.codPartida);
                    break;


                case "descripcion ASC":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;

                case "desPartida ASC":
                    q = q.OrderBy(b => b.desPartida);
                    break;
                case "desPartida DESC":
                    q = q.OrderByDescending(b => b.desPartida);
                    break;

                case "desPresupuesto ASC":
                    q = q.OrderBy(b => b.desPresupuesto);
                    break;
                case "desPresupuesto DESC":
                    q = q.OrderByDescending(b => b.desPresupuesto);
                    break;

                case "parcial ASC":
                    q = q.OrderBy(b => b.parcial);
                    break;
                case "parcial DESC":
                    q = q.OrderByDescending(b => b.parcial);
                    break;

                case "precio ASC":
                    q = q.OrderBy(b => b.precio);
                    break;
                case "precio DESC":
                    q = q.OrderByDescending(b => b.precio);
                    break;


                case "unidad ASC":
                    q = q.OrderBy(b => b.unidad);
                    break;
                case "unidad DESC":
                    q = q.OrderByDescending(b => b.unidad);
                    break;

                
                default:
                    q = q.OrderBy(b => b.idInternal).OrderByDescending(p => p.codigo);
                    break;
            }
            return q;
        }

        private IQueryable<RecursoListInfo> ApplySelect_RecursoListInfo()
        {
            var q = from i in DbUtil.Db.Recursos
                    select new RecursoListInfo
                    {
                        
                        cantidad = i.cantidad.Value,
                        cantidadStr=String.Format("{0:N4}",i.cantidad.Value),
                        codigo = i.codigo,
                        codPartida = i.Partida.codigo,
                        descripcion = i.descripcion,
                        desPartida = i.Partida.descripcion,
                        desPresupuesto=i.Partida.Presupuesto.abreviacion,
                        idInternal = i.idInternal,
                        parcial=i.parcial.Value,
                        parcialStr=String.Format("{0} {1:N}", i.Partida.Presupuesto.Moneda.simbol, i.parcial),
                        precio =  i.precio.Value,
                        precioStr = String.Format("{0} {1:N}", i.Partida.Presupuesto.Moneda.simbol, i.precio),
                        unidad=i.unidad,
                        bitsel=i.bitsel.Value,
                        idPresupuesto=i.Partida.idPresupuesto,
                        parcialUso=i.parcialUso.Value,
                        idgrupo=i.grupo.Value,
                        idMoneda=i.Partida.Presupuesto.Moneda.idInternal,
                        simbolMoneda=i.Partida.Presupuesto.Moneda.simbol,
                        
                    };
            return q;
        }


        #endregion

    }

    

  

   



}

